﻿using System;
using System.Configuration;
using System.Linq;
using System.Reflection;
using ExcelAutomator.Configuration;
using ExcelAutomator.Configuration.Internal;

namespace ExcelAutomator
{
	public abstract class ExcelParameterPatternResolverBase : IParameterPatternResolver
	{
		private readonly ILookup<string, ParameterMappingElement> m_ExcelParameterPatternMappingById;

		public abstract string PatternId { get; }

		#region ctor

		public ExcelParameterPatternResolverBase()
		{
			var config = ConfigurationManager.OpenExeConfiguration(Assembly.GetCallingAssembly().ManifestModule.Name);
			var section = config.GetSection(Constants.ExcelAutomatorConfigSection) as ExcelAutomatorSection;

			if (section != null)
			{
				m_ExcelParameterPatternMappingById = section.ParameterMappings.OfType<ParameterMappingElement>()
					.DistinctBy(x => x.AttributeName)
					.OrderByDescending(x => x.AttributeName.Length)
					.ToLookup(x => x.Id);
			}
			else
			{
				throw new InvalidOperationException("The <excelAutomation> section could not be loaed from application config file.");
			}
		}

		#endregion


		public string Resolve(string value, string propertyName, ExecutionContext context)
		{
			if (m_ExcelParameterPatternMappingById.Contains(PatternId))
			{
				foreach (var mappingElement in m_ExcelParameterPatternMappingById[PatternId])
				{
					if (mappingElement.AttributeName.Equals(propertyName, StringComparison.OrdinalIgnoreCase))
					{
						return OnResolve(value, mappingElement.ExecutionContextConfiguration, context);
					}

					if (mappingElement.AttributeName.Equals("*"))
					{
						return OnResolve(value, mappingElement.ExecutionContextConfiguration, context);
					}
				}
			}
			return value;
		}

		public abstract string OnResolve(string value, ExecutionContextConfiguration contextConfiguration, ExecutionContext context);

	}
}
